﻿using System;
using System.Text.RegularExpressions;
using System.Xml;
using SDT.Libraries.Mapper;

namespace SDT.CrawlSystem.Servers.Filters
{
    /// <summary>
    /// Written by TungNX
    /// </summary>
    public sealed partial class DateFilter
    {
        public sealed class Formatter
        {
            private const string TODAY = "TODAY";
            private const string TOMORROW = "TOMORROW";
            public enum DATE
            {
                NA, TODAY, TOMORROW
            };

            public static DATE FromString(string s)
            {
                if (s == null)
                    return DATE.NA;
                switch (s.Trim().ToUpper())
                {
                    case TODAY:
                        return DATE.TODAY;
                    case TOMORROW:
                        return DATE.TOMORROW;
                    default:
                        return DATE.NA;
                };
            }

            private StringIntMapItem DateFormat = null;

            private StringStringMapItem TimeFormat = null;

            private string StringFormat = null;

            public Formatter(XmlNode n)
            {
                if (n == null)
                    throw new ArgumentNullException();

                if (n.Attributes["Format"] != null)
                    StringFormat = n.Attributes["Format"].Value.Trim();

                var _n = n.SelectSingleNode("Date");
                if (_n != null)
                {
                    
                    var name = _n.InnerText;
                    var val = FromString(_n.Attributes["Value"] != null ? _n.Attributes["Value"].Value : null);
                    DateFormat = new StringIntMapItem(name, (int)val);
                }

                _n = n.SelectSingleNode("Time");
                if (_n != null)
                {
                    var name = _n.InnerText.Trim();
                    var val = _n.Attributes["Format"] != null ? _n.Attributes["Format"].Value : "HH:mm";
                    TimeFormat = new StringStringMapItem(name, val);
                }
            }

            public DateTime GetDateTime(string input, out bool ReturnDefault)
            {
                ReturnDefault = true;

                if (input == null || (StringFormat == null && DateFormat == null && TimeFormat == null))
                    return DateTime.Now;

                if(StringFormat != null)
                    try
                    {
                        return DateTime.ParseExact(input.Trim(), StringFormat, null);
                    }
                    catch { return DateTime.Now; }

                var d = DateTime.Now;
                if (DateFormat != null && input.ToLower().Contains(DateFormat.Name.ToLower()))
                {
                    ReturnDefault = false;

                    switch ((DATE)DateFormat.Value)
                    {
                        case DATE.TOMORROW:
                            d = d.AddDays(-1);
                            break;
                        default:
                            break;
                    }

                    if (TimeFormat != null && TimeFormat.Name.Length > 0)
                    {
                        var m = Regex.Match(input, TimeFormat.Name);
                        if (m.Success)
                        {
                            var time = DateTime.ParseExact(m.Value, TimeFormat.Value, null);

                            d = d.AddMilliseconds(-d.Millisecond).AddSeconds(-d.Second).AddMinutes(-d.Minute).AddHours(-d.Hour)
                                .AddHours(time.Hour).AddMinutes(time.Minute);
                        }
                    }
                }
                
                return d;
            }


        };
    }
}